package view.Tabs;

import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Text;

import view.Items.SearchResultItemGUI;
import view.Windows.ErrorMessageGUI;

import commons.Constants;
import commons.Entities.LegenCharacterThin;
import commons.Entities.SearchResults;

import controller.ControllerFunctions;

public final class SearchGUI {

	private final static SearchGUI INSTANCE = new SearchGUI();

	public static SearchGUI get() {
		return INSTANCE;
	}

	public SearchGUI() {

	}

	// final public Shell shlMain;
	protected Color cBackgroundColor;
	protected Font fHeadFont;
	protected Display mainDisp;
	protected Composite shlMain;
	protected CTabFolder ctfHome;
	protected Group grSearchResults;
	protected ScrolledComposite scResults;
	protected Composite cResults;
	protected ScrollBar sb;
	protected Label lblFoundResults;

	public void SearchGUIRun() {
		// main display for the login page
		shlMain.setBounds(10, 10, 900, 700);
		setBackgroundColor(new Color(mainDisp, 240, 240, 240));
		final Color clrWhite = new Color(mainDisp, 255, 255, 255);

		// search group
		final Group grSearch = new Group(shlMain, 0);
		grSearch.setBounds(50, 30, 800, 140);
		Label lblSearch = new Label(shlMain, 0);
		lblSearch.setForeground(clrWhite);
		lblSearch.setText("Search");
		lblSearch.setBounds(60, 30, 50, 30);
		lblSearch.moveAbove(grSearch);
		lblSearch.setAlignment(SWT.CENTER);

		// search by name
		Label lblByName = new Label(grSearch, 0);
		lblByName.setText("Name: ");
		lblByName.setBounds(200, 30, 70, 20);
		lblByName.setForeground(clrWhite);

		final Text txCharacterName = new Text(grSearch, SWT.BORDER);
		txCharacterName.setBounds(280, 30, 160, 25);

		// search by gender
		Label lblByGender = new Label(grSearch, 0);
		lblByGender.setText("Gender: ");
		lblByGender.setBounds(200, 60, 70, 20);
		lblByGender.setForeground(clrWhite);

		final Text txCharacterGender = new Text(grSearch, SWT.BORDER);
		txCharacterGender.setBounds(280, 60, 160, 25);

		// search by species
		Label lblBySpecies = new Label(grSearch, 0);
		lblBySpecies.setText("Species: ");
		lblBySpecies.setBounds(200, 90, 70, 20);
		lblBySpecies.setForeground(clrWhite);

		final Text txCharacterSpecies = new Text(grSearch, SWT.BORDER);
		txCharacterSpecies.setBounds(280, 90, 160, 25);

		FontData fontData = new FontData("Ariel", 10, SWT.BOLD);
		setHeadFont(new Font(mainDisp, fontData));

		// search button
		Button btnSearch = new Button(grSearch, SWT.NONE);
		btnSearch.setFont(getHeadFont());
		btnSearch.setText("Search");
		btnSearch.setBounds(470, 60, 100, 30);
		btnSearch.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				ControllerFunctions.get().getSearchResults(txCharacterName.getText(), txCharacterGender.getText(), txCharacterSpecies.getText());
			}
		});

		// search when pressing 'enter'
		shlMain.addListener(SWT.Traverse, new Listener() {

			public void handleEvent(Event event) {
				switch (event.detail) {
					case SWT.TRAVERSE_RETURN:
						ControllerFunctions.get().getSearchResults(txCharacterName.getText(), txCharacterGender.getText(), txCharacterSpecies.getText());
				}
			}
		});

		// search results group
		grSearchResults = new Group(shlMain, SWT.V_SCROLL);
		grSearchResults.setBounds(50, 190, 800, 400);
		grSearchResults.setBackgroundMode(SWT.INHERIT_FORCE);
		scResults = new ScrolledComposite(grSearchResults, SWT.V_SCROLL | SWT.BORDER);
		scResults.setBounds(0, 0, 800, 400);
		scResults.setExpandVertical(true);
		cResults = new Composite(scResults, 0);
		lblFoundResults = new Label(shlMain, 0);
		sb = scResults.getVerticalBar();
		sb.setVisible(true);

		Label lblEmptyLine = new Label(scResults, 0);
		lblEmptyLine.setBounds(5, 0, 790, 15);
		lblEmptyLine.moveAbove(cResults);
		Label lblSearchResults = new Label(shlMain, 0);
		lblSearchResults.setForeground(clrWhite);
		lblSearchResults.setText("Search Results");
		lblSearchResults.setBounds(60, 180, 100, 30);
		lblSearchResults.moveAbove(grSearchResults);
		lblSearchResults.setAlignment(SWT.CENTER);
	}

	/**
	 * udpate the search results
	 * 
	 * @param searchResults
	 */
	public void updateSearchResults(SearchResults searchResults) {
		final List<LegenCharacterThin> lctList = searchResults.getCharacterDetails();
		final Color clrWhite = new Color(mainDisp, 255, 255, 255);
		cResults.dispose();
		cResults = new Composite(scResults, 0);
		cResults.setBounds(0, 0, 800, 30 + lctList.size() * 50);
		sb.addListener(SWT.Selection, new Listener() {

			public void handleEvent(Event e) {
				Point location = cResults.getLocation();
				location.y = -sb.getSelection() * ((30 + lctList.size() * 53) / sb.getMaximum());
				cResults.setLocation(location);
			}
		});

		int i = 0;
		for (LegenCharacterThin lct : lctList) {
			new SearchResultItemGUI(lct.getCharacterID(), lct.getCharacterName(), lct.getGender(), lct.getSpecies(), lct.getAppearsInTheseFictionalUniverses(), 10, 15 + 50 * (i), cResults, mainDisp,
					ctfHome);
			i++;
		}

		Label lblHLine = new Label(cResults, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
		lblHLine.setBounds(10, 20 + lctList.size() * 50, 750, 10);
		lblHLine.setForeground(clrWhite);

		lblFoundResults.dispose();
		lblFoundResults = new Label(shlMain, 0);
		int size = lctList.size() <= 100 ? lctList.size() : 100;
		lblFoundResults.setText("Results Found: " + size);
		lblFoundResults.setBounds(50, 590, 150, 30);
		lblFoundResults.setForeground(clrWhite);

		if (searchResults.isTooMany()) {
			ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, "There are more than " + Constants.SEARCH_RESULTS_LIMIT + " results. please focus your search.");
			errorMsg.showGUI(mainDisp);
			return;
		}

	}

	public Color getBackgroundColor() {
		return cBackgroundColor;
	}

	public void setBackgroundColor(Color cBackgroundColor) {
		this.cBackgroundColor = cBackgroundColor;
	}

	public Font getHeadFont() {
		return fHeadFont;
	}

	public void setHeadFont(Font fHeadFont) {
		this.fHeadFont = fHeadFont;
	}

	public Display getMainDisp() {
		return mainDisp;
	}

	public Composite getShlMain() {
		return shlMain;
	}

	public CTabFolder getCtfHome() {
		return ctfHome;
	}

	public void setMainDisp(Display mainDisp) {
		this.mainDisp = mainDisp;
	}

	public void setShlMain(Composite shlMain) {
		this.shlMain = shlMain;
	}

	public void setCtfHome(CTabFolder ctfHome) {
		this.ctfHome = ctfHome;
	}
}
